package jiguang

import (
	"xlq-demo/library/config"
	"net/http"
	"bytes"
	"encoding/base64"
	"io/ioutil"
	"github.com/tidwall/gjson"
	"fmt"
	"encoding/json"
)

type PushBody struct {
	Platform interface{} `json:"platform"`
	Audience interface{} `json:"audience"`
	Notification *Notification `json:"notification"`
	Options *Options `json:"options"`
}
type Notification struct {
	Android *NotificationAndroid `json:"android"`
	Ios *NotificationIos `json:"ios"`
}
type NotificationAndroid struct {
	Alert string `json:"alert"`
	Title string `json:"title"`
	Extras interface{} `json:"extras"`
}
type NotificationIos struct {
	Alert string `json:"alert"`
	Sound string `json:"sound"`
	Badge string `json:"badge"`
	//推送唤醒
	ContentAvailable bool `json:"content-available"`
	Extras interface{} `json:"extras"`
}
type Options struct {
	//环境 true-生产 false-开发
	ApnsProduction bool `json:"apns_production"`
}

type PushIn struct {
	//推送类型 1-全推 2-tag推 3-个推
	Type int
	Tags []string
	Alias []string
	Title string
	Content string
	//额外数据
	Extra interface{}
}
func Push(in *PushIn) error {
	pushBody := new(PushBody)

	pushBody.Platform = "all"
	pushBody.Notification = &Notification{
		Android: &NotificationAndroid{
			Alert: in.Content,
			Title: in.Title,
			Extras: in.Extra,
		},
		Ios: &NotificationIos{
			Alert: in.Content,
			Sound: "default",
			Badge:  "+1",
			ContentAvailable: true,
			Extras: in.Extra,
		},
	}
	pushBody.Options = &Options{
		ApnsProduction: config.Config.Jpush.Env,
	}

	switch in.Type {
	case 1:
		//全推
		pushBody.Audience = "all"

		reqBody,err := json.Marshal(pushBody)
		if err != nil {
			return err
		}
		return pushSend(reqBody)

	case 2:
		//Tag推 一次推送最多20个
		tagLen := len(in.Tags)
		if tagLen == 0 {
			return fmt.Errorf("请提供tags")
		}


		for i:=0;i<tagLen;i+=20 {
			left := i
			right := i+20
			if right > tagLen {
				right = tagLen
			}
			pushBody.Audience = map[string]interface{}{
				"tag": in.Tags[left:right],
			}
			reqBody,err := json.Marshal(pushBody)
			if err != nil {
				return err
			}
			err = pushSend(reqBody)
			if err != nil {
				return err
			}
		}
		return nil

	case 3:
		//个推 每次最多1000个,需要循环处理
		aliasLen := len(in.Alias)
		if aliasLen == 0 {
			return fmt.Errorf("请提供tags")
		}
		for i:=0;i<aliasLen;i+=1000 {
			left := i
			right := i+1000
			if right > aliasLen {
				right = aliasLen
			}
			pushBody.Audience = map[string]interface{}{
				"alias": in.Alias[left:right],
			}
			reqBody,err := json.Marshal(pushBody)
			if err != nil {
				return err
			}
			err = pushSend(reqBody)
			if err != nil {
				return err
			}
		}
		return nil

	}
	return fmt.Errorf("UnKonw Type")
}


//http请求
func pushSend(body []byte) error {
	url := "https://api.jpush.cn/v3/push"

	req,err := http.NewRequest("POST",url,bytes.NewReader(body))
	if err != nil {
		return err
	}
	req.Header.Set("Authorization","Basic "+base64.StdEncoding.EncodeToString([]byte(config.Config.Jpush.AppKey+":"+config.Config.Jpush.AppSecret)))
	req.Header.Set("Content-Type","application/json")

	client := &http.Client{}

	res,err := client.Do(req)
	if err != nil {
		return err
	}

	defer res.Body.Close()
	resBody,err := ioutil.ReadAll(res.Body)
	if err != nil {
		return err
	}

	resObj := gjson.ParseBytes(resBody)
	if errObj := resObj.Get("error");errObj.Exists() {
		//有报错
		errCode := errObj.Get("code").Int()
		errMsg := errObj.Get("message").String()
		return fmt.Errorf("%d: %s",errCode,errMsg)
	}
	return nil
}



